using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Windows.Markup;
using System.Windows.Media;
using DimensionsHelper.Common.TableFormatter;

namespace DimensionsHelper.Client.Helpers;

public record FontFamilyInfo(string Name, FontFamily Family);


public static class FontFamilyHelper
{
    private static readonly Dictionary<string, FontFamilyInfo> LocalNameToFontFamily = new();
    private static readonly Dictionary<FontFamily, FontFamilyInfo> FontFamilyToLocalName = new();

    public static readonly IReadOnlyList<string> SystemFontNames;

    public static readonly IReadOnlyList<FontFamilyInfo> SystemFontInfos;


    static FontFamilyHelper()
    {
        foreach (FontFamily? font in Fonts.SystemFontFamilies)
        {
            string fontName = font.Source;

            if (font.FamilyNames.TryGetValue(XmlLanguage.GetLanguage(new CultureInfo("zh-CN").IetfLanguageTag),
                    out string? familyLocalName))
            {
                fontName = familyLocalName;
            }
            else if (font.FamilyNames.TryGetValue(XmlLanguage.GetLanguage(new CultureInfo("zh-TW").IetfLanguageTag),
                         out familyLocalName))
            {
                fontName = familyLocalName;
            }

            FontFamilyInfo info = new(fontName, font);
            LocalNameToFontFamily.TryAdd(fontName, info);
            FontFamilyToLocalName.TryAdd(font, info);
        }

        SystemFontNames = LocalNameToFontFamily.Keys.ToList();
        SystemFontInfos = LocalNameToFontFamily.Values.ToList();

        DefaultFontFamily = new FontFamilyInfo(TableFormatterDefaultValues.FontFamily,
            GetFontFamily(TableFormatterDefaultValues.FontFamily));
    }


    public static FontFamilyInfo DefaultFontFamily { get; }


    public static bool TryGetFontFamilyInfo(string fontName, [MaybeNullWhen(false)] out FontFamilyInfo info)
    {
        return LocalNameToFontFamily.TryGetValue(fontName, out info);
    }


    public static bool TryGetFontFamilyInfo(FontFamily fontFamily, [MaybeNullWhen(false)] out FontFamilyInfo info)
    {
        return FontFamilyToLocalName.TryGetValue(fontFamily, out info);
    }


    public static bool TryGetFontFamily(string fontName, [MaybeNullWhen(false)] out FontFamily fontFamily)
    {
        fontFamily = null;

        if (LocalNameToFontFamily.TryGetValue(fontName, out FontFamilyInfo? info))
        {
            fontFamily = info.Family;
            return true;
        }

        return false;
    }


    public static bool TryGetFontName(FontFamily font, [MaybeNullWhen(false)] out string fontName)
    {
        fontName = null;

        if (FontFamilyToLocalName.TryGetValue(font, out FontFamilyInfo? info))
        {
            fontName = info.Name;
            return true;
        }

        return false;
    }


    public static FontFamily GetFontFamily(string fontName)
    {
        return LocalNameToFontFamily[fontName].Family;
    }


    public static string GetFontName(FontFamily font)
    {
        return FontFamilyToLocalName[font].Name;
    }
}